<template>
  <el-dialog
    v-model="visible"
    width="100%"
    :fullscreen="true"
    :close-on-click-modal="false"
    :close-on-press-escape="true"
    :show-close="true"
    :before-close="handleClose"
    class="mobile-comment-modal"
    :class="{ 'keyboard-open': isKeyboardOpen }"
  >
    <!-- 固定标题 -->
    <div class="fixed-header">
      <div class="modal-header">
        <h2 class="modal-title">{{ modalTitle }}</h2>
        <el-button 
          type="text" 
          @click="handleClose"
          class="close-btn"
        >
          <el-icon><Close /></el-icon>
        </el-button>
      </div>
    </div>
    
    <div class="modal-content">
      <!-- 评论列表 -->
      <div class="comment-list-container" v-if="comments.length > 0">
        <div class="comment-list" ref="commentListRef">
          <CommentItem
            v-for="comment in comments"
            :key="comment.ID"
            :comment="comment"
            :replying-to="replyingTo"
            :replying-to-author="replyingToAuthor"
            @reply-click="handleReply"
            @delete="handleDelete"
            @edit="handleEdit"
          />
        </div>
      </div>
      
      <!-- 空状态 -->
      <div class="empty-comments" v-else>
        <el-empty description="暂无评论" :image-size="80">
          <template #description>
            <span class="empty-text">还没有人评论，来抢沙发吧~</span>
          </template>
        </el-empty>
      </div>
      
      <!-- 评论输入区域 -->
      <div class="comment-input-container">
        <div class="comment-input" v-if="replyingTo">
          <div class="reply-info">
            <el-icon class="reply-icon"><ChatDotRound /></el-icon>
            <span class="reply-text">回复 @{{ replyingToAuthor }}</span>
            <el-button 
              type="text" 
              size="small" 
              @click="cancelReply"
              class="cancel-reply-btn"
            >
              取消
            </el-button>
          </div>
        </div>
        
        <div class="comment-input">
          <el-input
            v-model="newComment"
            type="textarea"
            :rows="3"
            placeholder="写下你的评论... 支持 @ 提及"
            :maxlength="500"
            show-word-limit
            @focus="handleInputFocus"
            @keydown.ctrl.enter="submitComment"
            @input="handleCommentInput"
            @keydown.native="handleKeyDown"
            @compositionstart="isComposing = true"
            @compositionend="onCompositionEnd"
            class="comment-textarea"
          />

          <!-- @ 提及人员列表 -->
          <div v-if="showMentionList" class="mention-list-container">
            <div class="mention-list">
              <div class="mention-header">
                <el-icon class="mention-icon"><User /></el-icon>
                <span class="mention-title">选择要@的人员</span>
                <span class="mention-count" v-if="filteredMentionUsers.length > 0">{{ filteredMentionUsers.length }}人</span>
              </div>
              <div class="mention-items" v-if="filteredMentionUsers.length > 0">
                <div
                  v-for="user in filteredMentionUsers"
                  :key="user.id"
                  class="mention-item"
                  @click="selectMentionUser(user)"
                >
                  <div class="mention-avatar">
                    <el-avatar :size="32" :src="user.avatar" class="user-avatar">
                      {{ user.name?.charAt(0) }}
                    </el-avatar>
                  </div>
                  <div class="mention-info">
                    <div class="mention-name" v-html="highlightSearchText(user.name, mentionSearchText)"></div>
                  </div>
                  <div class="mention-action">
                    <el-icon class="action-icon"><Plus /></el-icon>
                  </div>
                </div>
              </div>
              <div v-else class="mention-no-results">
                <el-icon class="no-results-icon"><Search /></el-icon>
                <span class="no-results-text">未找到匹配的人员</span>
                <div class="no-results-tip">尝试输入姓名关键词</div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 提交按钮 -->
        <div class="comment-actions">
          <el-button
            type="primary"
            @click="submitComment"
            :disabled="!newComment.trim() || isSubmittingComment"
            :loading="isSubmittingComment"
            class="submit-btn"
          >
            {{ isSubmittingComment ? '提交中...' : '提交评论' }}
          </el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { ChatDotRound, Close, User, Plus, Search } from '@element-plus/icons-vue'
import CommentItem from '@/views/daily/daily/CommentItem.vue'
import { ToComments, GetToComments, GetDailyUserListByDepartment } from '@/api/newDemands/index'
import type { Comment } from '@/views/daily/daily/CommentItem.vue'

interface Props {
  modelValue: boolean
  reportId: number
  currentUser: any
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'comment-submitted'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

// 响应式数据
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const modalTitle = computed(() => {
  return `评论 (${comments.value.length})`
})

const comments = ref<Comment[]>([])
const newComment = ref('')
const replyingTo = ref<number | undefined>()
const replyingToAuthor = ref('')
const isSubmittingComment = ref(false)
const isKeyboardOpen = ref(false)
const commentListRef = ref<HTMLElement>()

// @ 提及相关
interface Staff { id: string; name: string; avatar?: string }
const showMentionList = ref(false)
const filteredMentionUsers = ref<Staff[]>([])
const mentionStartIndex = ref(-1)
const mentionSearchText = ref('')
const isComposing = ref(false)
const mentionUsers = ref<Staff[]>([])
// 在触发 '@' 后的保护时间，避免 iOS 立即触发一次空输入把面板关掉
const lastAtTriggerMs = ref(0)
const hasLoadedMentionUsers = ref(false)

const initMentionUsers = async () => {
  try {
    const { data } = await GetDailyUserListByDepartment('all')
    if (data.code === 200) {
      mentionUsers.value = (data.data || []).map((u: any) => ({
        id: u.uuid || u.userWxId || u.id || String(Math.random()),
        name: u.userName || u.nickName || u.name,
        avatar: u.avatar || u.headerImg || ''
      }))
      hasLoadedMentionUsers.value = true
    }
  } catch (e) {
    console.error('获取@人员失败:', e)
  }
}

const ensureMentionUsers = async () => {
  if (!hasLoadedMentionUsers.value) {
    await initMentionUsers()
  }
}

const openMentionList = async () => {
  // 确保有可选用户
  if (mentionUsers.value.length === 0) {
    await ensureMentionUsers()
  }
  showMentionList.value = true
  filteredMentionUsers.value = mentionUsers.value
  lastAtTriggerMs.value = Date.now()
}

// 监听输入：支持 iOS 输入法
const handleCommentInput = () => {
  if (isComposing.value) return
  const text = newComment.value || ''
  let cursorPos = text.length
  const textarea = document.querySelector('.comment-textarea textarea') as HTMLTextAreaElement | null
  if (textarea && typeof textarea.selectionStart === 'number') cursorPos = textarea.selectionStart

  // 如果刚输入空格，则关闭人员列表
  if (text.charAt(cursorPos - 1) === ' ' && showMentionList.value) {
    showMentionList.value = false
    mentionStartIndex.value = -1
    mentionSearchText.value = ''
    filteredMentionUsers.value = []
    return
  }

  // 更宽松：只要文本末尾是 @ 就展开（不依赖光标）
  if (/@$/.test(text)) {
    mentionStartIndex.value = Math.max(0, text.length - 1)
    mentionSearchText.value = ''
    openMentionList()
    return
  }

  const lastAtPos = text.lastIndexOf('@', cursorPos - 1)
  if (lastAtPos < 0 || cursorPos <= lastAtPos) {
    showMentionList.value = false
    mentionStartIndex.value = -1
    mentionSearchText.value = ''
    filteredMentionUsers.value = []
    return
  }

  mentionStartIndex.value = lastAtPos
  mentionSearchText.value = text.substring(lastAtPos + 1, cursorPos)

  // 如果检索词里出现空格，认为结束本次提及，关闭列表
  if (mentionSearchText.value.includes(' ')) {
    showMentionList.value = false
    mentionStartIndex.value = -1
    mentionSearchText.value = ''
    filteredMentionUsers.value = []
    return
  }

  showMentionList.value = true
  const searchLower = mentionSearchText.value.toLowerCase()
  filteredMentionUsers.value = mentionUsers.value.filter(u => (u.name || '').toLowerCase().includes(searchLower))
}

const onCompositionEnd = () => {
  isComposing.value = false
  setTimeout(() => handleCommentInput(), 0)
}

const handleKeyDown = (e: KeyboardEvent) => {
  // iOS 输入法上屏延迟更大：放宽到 80ms
  setTimeout(() => {
    const text = newComment.value || ''
    const textarea = document.querySelector('.comment-textarea textarea') as HTMLTextAreaElement | null
    const cursorPos = textarea?.selectionStart ?? text.length

    // 空格键：关闭列表
    if ((e.key === ' ' || text.charAt(cursorPos - 1) === ' ') && showMentionList.value) {
      showMentionList.value = false
      mentionStartIndex.value = -1
      mentionSearchText.value = ''
      filteredMentionUsers.value = []
      return
    }

    if (/@$/.test(text)) {
      mentionStartIndex.value = Math.max(0, text.length - 1)
      mentionSearchText.value = ''
      openMentionList()
      return
    }

    if (showMentionList.value) {
      const lastAtPos = text.lastIndexOf('@', cursorPos - 1)
      if (lastAtPos >= 0) {
        mentionStartIndex.value = lastAtPos
        mentionSearchText.value = text.substring(lastAtPos + 1, cursorPos)
        // 检索词中出现空格则关闭
        if (mentionSearchText.value.includes(' ')) {
          showMentionList.value = false
          mentionStartIndex.value = -1
          mentionSearchText.value = ''
          filteredMentionUsers.value = []
          return
        }
        const searchLower = mentionSearchText.value.toLowerCase()
        filteredMentionUsers.value = mentionUsers.value.filter(u => (u.name || '').toLowerCase().includes(searchLower))
      } else {
        // 同样应用保护时间
        if (Date.now() - lastAtTriggerMs.value >= 200) {
          showMentionList.value = false
        }
      }
    }

    if (e.key === 'Backspace' || e.key === 'Delete') {
      const lastAtPos = text.lastIndexOf('@', cursorPos - 1)
      const searchText = lastAtPos >= 0 ? text.substring(lastAtPos + 1, cursorPos).trim() : ''
      if (lastAtPos < 0 || cursorPos <= lastAtPos || searchText === '') {
        if (Date.now() - lastAtTriggerMs.value >= 200) {
          showMentionList.value = false
          mentionStartIndex.value = -1
          mentionSearchText.value = ''
          filteredMentionUsers.value = []
        }
      }
    }
  }, 80)
}

const selectMentionUser = (user: Staff) => {
  if (mentionStartIndex.value >= 0 && user) {
    const textBefore = newComment.value.substring(0, mentionStartIndex.value)
    const textAfter = newComment.value.substring(mentionStartIndex.value + mentionSearchText.value.length + 1)
    newComment.value = `${textBefore}@${user.name} ${textAfter}`
    showMentionList.value = false
    nextTick(() => {
      const input = document.querySelector('.comment-textarea textarea') as HTMLTextAreaElement | null
      if (input) {
        input.focus()
        const cursor = mentionStartIndex.value + user.name.length + 2
        input.setSelectionRange(cursor, cursor)
      }
    })
  }
}

// 高亮搜索文本
const highlightSearchText = (text?: string, searchText?: string) => {
  const t = text || ''
  const s = searchText || ''
  if (!s) return t
  const regex = new RegExp(`(${s})`, 'gi')
  return t.replace(regex, '<mark style="background:#fef3c7;color:#92400e;border-radius:3px;padding:1px 2px;">$1</mark>')
}

// 获取评论列表
const getComments = async () => {
  if (!props.reportId) return
  
  try {
    const { data } = await GetToComments(props.reportId)
    if (data.code === 200) {
      const list = data.data || []
      comments.value = list.map((item: any) => ({
        ID: item.ID,
        userName: item.userName,
        checkDailyComments: item.checkDailyComments,
        time: item.createAt,
        replyTo: item.replyTo || undefined,
        replyToAuthor: item.replyToAuthor || undefined,
        replies: (item.replies || []).map((reply: any) => ({
          ID: reply.ID,
          userName: reply.userName,
          checkDailyComments: reply.checkDailyComments,
          time: reply.createAt,
          replyTo: reply.replyTo || undefined,
          replyToAuthor: reply.replyToAuthor || undefined,
          replies: reply.replies || []
        }))
      }))
    }
  } catch (error) {
    console.error('获取评论失败:', error)
  }
}

// 提交评论（保持原逻辑）
const submitComment = async () => {
  if (!newComment.value.trim() || !props.reportId || isSubmittingComment.value) return
  
  isSubmittingComment.value = true
  try {
    const mentionedUsers = extractMentionedUsers(newComment.value)
    const { data } = await ToComments({
      dailyId: props.reportId,
      newComment: newComment.value,
      mentionedUsers,
      replyTo: replyingTo.value || undefined,
      replyToAuthor: replyingTo.value ? replyingToAuthor.value : undefined
    })
    
    if (data.code === 200) {
      newComment.value = ''
      cancelReply()
      await getComments()
      ElMessage.success('评论提交成功')
      emit('comment-submitted')
    } else {
      ElMessage.error(data.msg)
    }
  } catch (error) {
    ElMessage.error('评论提交失败')
    console.error(error)
  } finally {
    isSubmittingComment.value = false
  }
}

// 从文本中提取 @ 的昵称数组
const extractMentionedUsers = (text: string) => {
  const mentions = text.match(/@([^\s@]+)/g) || []
  return mentions.map(m => m.substring(1))
}

// 处理回复/取消/列表等逻辑（保持不变）
const handleReply = (comment: Comment) => {
  replyingTo.value = comment.replyTo || comment.ID
  replyingToAuthor.value = comment.replyToAuthor || comment.userName || ''
  newComment.value = `@${replyingToAuthor.value} `
  nextTick(() => {
    const textarea = document.querySelector('.comment-textarea textarea') as HTMLTextAreaElement
    if (textarea) {
      textarea.focus()
      const textLength = textarea.value.length
      textarea.setSelectionRange(textLength, textLength)
    }
  })
}
const cancelReply = () => { replyingTo.value = undefined; replyingToAuthor.value = '' }
const handleDelete = async (commentId: number) => { console.log('删除评论:', commentId) }
const handleEdit = (comment: Comment) => { console.log('编辑评论:', comment) }

// 输入框相关
const handleInputFocus = () => {
  if (isMobile()) {
    isKeyboardOpen.value = true
    setTimeout(() => { scrollToBottom() }, 300)
  }
}
const isMobile = () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || window.innerWidth <= 768
const scrollToBottom = () => { if (commentListRef.value) commentListRef.value.scrollTop = commentListRef.value.scrollHeight }
const handleClose = () => { visible.value = false; cancelReply(); newComment.value = '' }

// 监听模态框显示状态
watch(visible, (newVal) => {
  if (newVal) {
    getComments()
    initMentionUsers()
    nextTick(() => { setTimeout(() => { scrollToBottom() }, 100) })
  }
})

// 当下拉打开时，给内部列表绑定独立滚动，避免被外层拦截
const bindMentionScrollGuards = () => {
  nextTick(() => {
    const wrap = document.querySelector('.mention-list') as HTMLElement | null
    if (!wrap) return
    const stop = (e: Event) => { e.stopPropagation(); }
    // 先移除再绑定，避免重复
    wrap.removeEventListener('touchmove', stop as any)
    wrap.removeEventListener('wheel', stop as any)
    wrap.addEventListener('touchmove', stop, { passive: false })
    wrap.addEventListener('wheel', stop, { passive: false })
  })
}

watch(showMentionList, (v) => { if (v) bindMentionScrollGuards() })

watch(comments, () => { nextTick(() => { scrollToBottom() }) }, { deep: true })

onMounted(() => { window.addEventListener('resize', handleResize) })
onUnmounted(() => { window.removeEventListener('resize', handleResize) })

// 键盘检测
const handleResize = () => {
  if (isMobile()) {
    const currentHeight = window.innerHeight
    const initialHeight = window.screen.height
    isKeyboardOpen.value = currentHeight < initialHeight * 0.75
  }
}
</script>

<style scoped>
.mobile-comment-modal {
  --el-dialog-border-radius: 0;
}

.mobile-comment-modal :deep(.el-dialog) {
  margin: 0;
  border-radius: 0;
  height: 100vh;
  display: block;
  overflow: hidden;
  position: relative;
}

.fixed-header { position: fixed; top: 0; left: 0; right: 0; z-index: 1000; background: #ffffff; border-bottom: 1px solid #e5e7eb; height: 60px; }
.modal-header { padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; background: #ffffff; height: 100%; }
.modal-title { font-size: 18px; font-weight: 600; color: #1f2937; margin: 0; }
.close-btn { color: #6b7280; font-size: 18px; padding: 4px; }
.close-btn:hover { color: #374151; }

.mobile-comment-modal :deep(.el-dialog__body) { padding: 0; flex: 1; display: flex; flex-direction: column; overflow: hidden; margin-top: 60px; height: calc(100vh - 60px); }

.modal-content { display: flex; flex-direction: column; height: calc(100vh - 60px); }

.comment-list-container { flex: 1; overflow: hidden; background: #f9fafb; display: flex; flex-direction: column; }
.comment-list { flex: 1; overflow-y: auto; padding: 16px; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; }
.comment-list::-webkit-scrollbar { width: 4px; }
.comment-list::-webkit-scrollbar-track { background: #f1f5f9; }
.comment-list::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 2px; }
.comment-list::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

.empty-comments { flex: 1; display: flex; align-items: center; justify-content: center; background: #f9fafb; }
.empty-text { color: #6b7280; font-size: 14px; }

.comment-input-container { background: #ffffff; border-top: 1px solid #e5e7eb; padding: 16px; flex-shrink: 0; z-index: 100; }
.reply-info { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; padding: 8px 12px; background: #eff6ff; border-radius: 8px; border: 1px solid #dbeafe; }
.reply-icon { color: #3b82f6; font-size: 16px; }
.reply-text { flex: 1; color: #1e40af; font-size: 14px; font-weight: 500; }
.cancel-reply-btn { color: #6b7280; font-size: 12px; padding: 4px 8px; }
.cancel-reply-btn:hover { color: #374151; }

.comment-input { margin-bottom: 12px; }
.comment-textarea :deep(.el-textarea__inner) { border-radius: 12px; border: 1px solid #d1d5db; padding: 12px; font-size: 16px; line-height: 1.5; resize: none; transition: border-color 0.2s ease; }
.comment-textarea :deep(.el-textarea__inner):focus { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); }

.comment-actions { display: flex; justify-content: flex-end; }
.submit-btn { border-radius: 8px; padding: 10px 24px; font-weight: 500; transition: all 0.2s ease; }
.submit-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.submit-btn.is-loading { background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); border-color: #3b82f6; }

/* @ 提及人员列表 */
.mention-list-container { position: relative; margin-top: 8px; }
/* 改为显示在输入框上方 */
.mention-list { position: absolute; bottom: 100%; top: auto; left: 0; margin-bottom: 110px; margin-top: 0; width: 100%; max-height: 220px; overflow-y: auto; background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.12); z-index: 2000; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; touch-action: pan-y; }
.mention-header { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #f8fafc; border-bottom: 1px solid #e5e7eb; }
.mention-icon { color: #3b82f6; }
.mention-title { font-size: 14px; color: #475569; font-weight: 600; }
.mention-count { font-size: 12px; color: #64748b; background: #eef2ff; border: 1px solid #e0e7ff; border-radius: 6px; padding: 2px 6px; font-weight: 600; margin-left: auto; }
.mention-items { max-height: 160px; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; touch-action: pan-y; }
.mention-item { display: flex; align-items: center; padding: 8px 12px; cursor: pointer; transition: all 0.2s; }
.mention-item:hover { background: #f8fafc; color: #3b82f6; }
.mention-avatar { flex-shrink: 0; margin-right: 10px; }
.user-avatar { background: #3b82f6; color: #fff; }
.mention-info { flex: 1; min-width: 0; }
.mention-name { font-size: 14px; font-weight: 500; color: #1e293b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mention-action { flex-shrink: 0; margin-left: 10px; opacity: 0; transition: opacity 0.2s ease; }
.mention-item:hover .mention-action { opacity: 1; }
.action-icon { color: #3b82f6; font-size: 16px; }
.mention-no-results { display: flex; flex-direction: column; align-items: center; padding: 16px 0; color: #64748b; font-size: 14px; }
.no-results-icon { font-size: 28px; margin-bottom: 8px; color: #94a3b8; }
.no-results-text { font-weight: 500; }
.no-results-tip { font-size: 12px; color: #94a3b8; margin-top: 4px; }

/* 键盘打开时的样式调整 */
.mobile-comment-modal.keyboard-open :deep(.el-dialog__body) { padding-bottom: 0; }
.mobile-comment-modal.keyboard-open .comment-input-container { position: relative; bottom: auto; }

/* 响应式 */
@media (max-width: 480px) {
  .mobile-comment-modal :deep(.el-dialog__header) { padding: 12px 16px; }
  .mobile-comment-modal :deep(.el-dialog__title) { font-size: 16px; }
  .comment-list { padding: 12px; }
  .comment-input-container { padding: 12px; }
  .comment-textarea :deep(.el-textarea__inner) { font-size: 16px; }
}

/* 动画 */
.mobile-comment-modal :deep(.el-dialog) { animation: slideInUp 0.3s ease-out; }
@keyframes slideInUp { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* 优化滚动性能 */
.comment-list { -webkit-overflow-scrolling: touch; scroll-behavior: smooth; }
/* 触摸体验 */
.comment-input-container { -webkit-tap-highlight-color: transparent; }
.submit-btn { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
</style>
